import React, { Component } from 'react';
import { graphql, compose } from 'react-apollo';
import gql from 'graphql-tag';
import { TouchableOpacity, ActivityIndicator, StyleSheet, Text } from 'react-native';
import { Button } from 'react-native-elements';
import { NavigationActions } from 'react-navigation'
import { primaryColor, executor } from '../utils';
import OrderPricingTable from './OrderPricingTable';
import OrderPayment from './OrderPayment';
import OrderShipping from './OrderShipping';
import OrderListItem from './OrderListItem';
import update from 'immutability-helper';
import moment from 'moment';
import { toast, paypalPay, saveCalendarEvents, ensureCalendarPromission } from '../utils';
import { clearNewOrderItems } from '../clientStorage';

const styles = StyleSheet.create({
  spinner: {
    marginRight: 16
  },
  buttonText: {
    color: primaryColor,
    fontSize: 17,
    padding: 16
  }
});

class OrderConfirmButton extends Component {
  state = { loading: false }
  onSubmit = () => {
    if (this.state.loading) return;
    const { createOrderV2, updateOrderV2, topUp } = this.props;
    const action = createOrderV2||updateOrderV2||topUp;
    const chinese = this.props.chinese;
    const { payment, toPayPrice, displayId, type, pickupCalendar,
      deliveryCalendar } = this.props.navigation.state.params;

    Promise.resolve((updateOrderV2&&payment==='paypal')?
      executor(this.props.paymentReauthorize).then(({res}) => {
        if (res&&res.paymentReauthorize) {
          return paypalPay(toPayPrice, `Order #${displayId} payment reauthorize`);
        }
      }):null)
      .then(paypalToken => executor(action, paypalToken))
      .then(({res}) => {
        this.setState({loading: false});
        if (res) {
          const {createOrderV2, updateOrderV2, topUpByCreditCard} = res;
          if (createOrderV2||updateOrderV2) {
            if (createOrderV2) {
              toast(chinese?'下单成功':'Place order success');
            } else if (updateOrderV2) {
              toast(chinese?'更新成功':'Update order success');
            } else {
              toast(chinese?'支付成功':'Payment success');
            }

            clearNewOrderItems(type==='premiumlaundry');
            const order = (updateOrderV2||createOrderV2)[0];
            this.props.navigation.dispatch(NavigationActions.reset({
              index: 1,
              actions: [
                NavigationActions.navigate({routeName: 'Main'}),
                NavigationActions.navigate({routeName: 'OrderDetail', params: {displayId:order.displayId,id:order.id,seriesId:order.seriesId}}),
              ]
            }));

            ensureCalendarPromission()
              .then(hasPermission => {
                if (!hasPermission) return;

                (createOrderV2||updateOrderV2).map(({displayId, pickup, type, delivery}) => {
                  if (pickup&&(updateOrderV2||pickupCalendar)) {
                    saveCalendarEvents(displayId, 'Pickup', pickup);
                  }
                  if (delivery&&(updateOrderV2||deliveryCalendar)) {
                    saveCalendarEvents(displayId, type==='aircon'?'Service':'Delivery', delivery);
                  }
                });
              })
          } else if (topUpByCreditCard) {
            toast(this.props.chinese?'充值成功':'Top up success');
            this.props.navigation.dispatch(NavigationActions.reset({
              index: 1,
              actions: [
                NavigationActions.navigate({routeName: 'Main'}),
                NavigationActions.navigate({routeName: 'TopUp'}),
              ]
            }));
          }
        }
      })
      .catch(err => this.setState({loading: false}));
    this.setState({loading: true});
  }
  render() {
    if (this.state.loading) {
      return <ActivityIndicator style={{marginVertical:32,marginHorizontal:16}} color={primaryColor}/>
    } else {
      const { createOrderV2, updateOrderV2, chinese, topUp } = this.props;
      const { capture } = this.props.navigation.state.params;

      let title;
      if (createOrderV2) {
        title = chinese?'下单':'Place Order';
      } else if (capture) {
        title = chinese?'支付':'Pay';
      } else if (updateOrderV2) {
        title = chinese?'确认':'Submit Update'
      } else if (topUp) {
        title = chinese?'确认':'Top Up';
      }

      return (
        <Button style={{margin: 16}} title={title} backgroundColor={primaryColor} onPress={this.onSubmit}/>
      );
    }
  }
}

const CALENDER_FRAGMENTS = gql`
  fragment CalenderEvent on Order {
    displayId
    type
    pickup {
      date
      address
      unitNumber
      postalCode
      flexible
    }
    delivery {
      date
      address
      unitNumber
      postalCode
      flexible
    }
  }
`;

const CREATE_NEW_ORDER = gql`
  mutation createOrderV2($type:String!,$paymentMethod:String!,$orderItems:[OrderItemInput],$pickup:ShippingInput!,
    $delivery:ShippingInput!,$voucherId:String,$promoCodeId:String,$index:String,$userId:String) {
    createOrderV2(type:$type,paymentMethod:$paymentMethod,orderItems:$orderItems,pickup:$pickup,delivery:$delivery,
      voucherId:$voucherId,promoCodeId:$promoCodeId,index:$index,userId:$userId) {
      id
      seriesId
      displayId
      voucherId
      ...CalenderEvent
      ...OrderListItem
    }
  }
  ${CALENDER_FRAGMENTS}
  ${OrderListItem.fragments.order}
`;

const UPDATE_ORDER = gql`
  mutation updateOrderV2($orderId:String!,$orderItems:[OrderItemInput],$pickup:ShippingInput
    ,$delivery:ShippingInput,$paymentMethod:String,$capture:Boolean) {
    updateOrderV2(orderId:$orderId,orderItems:$orderItems,pickup:$pickup,
      delivery:$delivery,paymentMethod:$paymentMethod,capture:$capture) {
      id
      seriesId
      ...CalenderEvent
      pricing {
        ...OrderPricingTable
      }
      payment {
        ...OrderPayment
      }
      pickup {
        ...OrderShipping
      }
      delivery {
        ...OrderShipping
      }
    }
  }
  ${CALENDER_FRAGMENTS}
  ${OrderPricingTable.fragments.pricing}
  ${OrderShipping.fragments.shipping}
  ${OrderPayment.fragments.payment}
`;

const REAUTHORIZE_CHECK = gql`
  mutation paymentReauthorize($orderId:String!,$orderItems:[OrderItemInput],$pickup:ShippingInput
    ,$delivery:ShippingInput) {
    paymentReauthorize(orderId:$orderId,orderItems:$orderItems,pickup:$pickup,delivery:$delivery)
  }
`;

const TOP_UP = gql`
  mutation topUpByCreditCard($topUpId:String!,$cardId:String,$paypalToken:String) {
    topUpByCreditCard(topUpId:$topUpId,cardId:$cardId,paypalToken:$paypalToken) {
      id
      credit
    }
  }
`;

const refreshLoginUser = [{
  query: gql`
    query RefreshUser {
      user {
        id
        credit
      }
      membership {
        id
        title
        badge
        description
      }
    }
  `,
}]

export default compose(
  graphql(CREATE_NEW_ORDER, {
    name: 'createOrderV2',
    props: ({ownProps: {chinese, navigation:{state:{params:{orderId, topUpId, type, payment, items, pickupDate,
      addressId, deliveryDate, deliveryAddressId, voucherId, promoCodeId, pickupFlexible, dropOffFlexible,
      express, pickupNote, deliveryNote, toPayPrice, userId}}}}, createOrderV2}) => {
      return {
        createOrderV2: (!orderId&&!topUpId)?(() => {
          if (payment==='paypal'&&isNaN(toPayPrice)) return Promise.reject(chinese?'对不起，系统无法找到合法的付款价格，请尝试重新选择您的衣物':'Sorry, system can not find a valid pricing, please try reselect your items.')
          
          return Promise.resolve((payment==='paypal')&&paypalPay(toPayPrice, 'New Order Payment'))
            .then((paypalToken) => createOrderV2({
              variables: {
                type,
                userId,
                paymentMethod: paypalToken||payment,
                orderItems: items,
                pickup: {
                  addressId,
                  date: pickupDate||deliveryDate,
                  flexible: pickupFlexible,
                  note: pickupNote
                },
                delivery: {
                  addressId: deliveryAddressId||addressId,
                  date: deliveryDate,
                  flexible: dropOffFlexible,
                  note: deliveryNote,
                  express: express?true:false
                },
                voucherId,
                promoCodeId
              },
              ...(payment==='credit')?{
                refetchQueries: refreshLoginUser
              }:{},
              updateQueries: {
                OrderList: (prev, { mutationResult }) => {
                  const newOrders = mutationResult.data.createOrderV2;

                  return update(prev, {
                    orders: {
                      $unshift: newOrders,
                    }
                  });
                },
                VoucherList: (prev, { mutationResult }) => {
                  const createOrderV2 = mutationResult.data.createOrderV2;
                  if (createOrderV2.voucherId) {
                    const index = prev.vouchers&&prev.vouchers.findIndex(item => item.id===createOrderV2.voucherId);
                    if (index >= 0) {
                      return update(prev, {
                        vouchers: {
                          $splice: [[index, 1]],
                        }
                      });
                    }
                  }

                  return prev;
                },
              },
            }));
        }):null
      }
    }
  }),
  graphql(UPDATE_ORDER, {
    name: 'updateOrderV2',
    props: ({ownProps: {navigation:{state:{params:{orderId, displayId, type, payment, items, pickupDate,
      addressId, deliveryDate, deliveryAddressId, voucherId, promoCodeId, pickupFlexible,
      dropOffFlexible, pickupNote, deliveryNote, express, stepper, toPayPrice, capture}}}}, updateOrderV2}) => {
      return {
        updateOrderV2: orderId?((paypalToken) => {
          return updateOrderV2({
              variables: {
                orderId,
                orderItems: items,
                ...addressId&&(pickupDate||deliveryDate)&&{
                  pickup: {
                    addressId,
                    date: pickupDate||deliveryDate,
                    flexible: pickupFlexible,
                    note: pickupNote
                  },
                },
                ...(deliveryAddressId||addressId)&&deliveryDate&&{
                  delivery: {
                    addressId: deliveryAddressId||addressId,
                    date: deliveryDate,
                    flexible: dropOffFlexible,
                    note: deliveryNote,
                    express: express?true:false
                  },
                },
                paymentMethod: paypalToken||payment,
                capture
              },
              ...(payment==='credit')?{
                refetchQueries: refreshLoginUser
              }:{}
            });
        }):null
      }
    }
  }),
  graphql(TOP_UP, {
    name: 'topUp',
    props: ({ownProps:{chinese, navigation:{state:{params:{topUpId, payment, toPayPrice}}}}, topUp}) => {
      return {
        topUp: topUpId?(() => {
            return new Promise((resolve, reject) => {
                if (payment==='paypal') {
                  paypalPay(toPayPrice, 'KnocKnocK top up')
                    .then(paypalToken => {
                      if (paypalToken) {
                        resolve({paypalToken})
                      } else {
                        reject(Error(chinese?'取消':'Cancelled'));
                      }
                    })
                    .catch(err => reject(err));
                } else {
                  resolve({cardId: payment});
                }
              })
              .then(args => topUp({
                variables:{
                  topUpId,
                  ...args
                },
                refetchQueries: [{
                  query: gql`
                    query TopupRefresh {
                      user {
                        id
                        credit
                      }
                    }
                  `,
                }],
              }));
          }):null
      };
    }
  }),
  graphql(REAUTHORIZE_CHECK, {
    name: 'paymentReauthorize',
    props: ({ownProps: {navigation:{state:{params:{orderId, type, payment, items, pickupDate,
      addressId, deliveryDate, deliveryAddressId, voucherId, promoCodeId, pickupFlexible,
      dropOffFlexible, pickupNote, deliveryNote, express, stepper}}}}, paymentReauthorize}) => {
      return {
        paymentReauthorize: () => paymentReauthorize({
          variables: {
            orderId,
            orderItems: items,
            ...addressId&&(pickupDate||deliveryDate)&&{
              pickup: {
                addressId,
                date: pickupDate||deliveryDate,
                flexible: pickupFlexible,
                note: pickupNote
              },
            },
            ...(deliveryAddressId||addressId)&&deliveryDate&&{
              delivery: {
                addressId: deliveryAddressId||addressId,
                date: deliveryDate,
                flexible: dropOffFlexible,
                note: deliveryNote,
                express: express?true:false
              },
            }
          }
        })
      }
    }
  })
)(OrderConfirmButton);

